﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using KPIS.GERP.GHRMS.APP.Classes;
using Telerik.Web.UI;
using System.Data;
using System.Collections;
using KPIS.GERP.GHRMS.BLL;
using KPIS.GERP.GHRMS.IBLL;
using KPIS.GERP.GHRMS.MODEL;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Web;
using KPIS.GERP.GHRMS.APP.Classes;
using KPIS.GERP.GHRMS.APP.RuleAbsenceService;
using KPIS.GERP.GHRMS.BLL;
using KPIS.GERP.GHRMS.IBLL;
using KPIS.GERP.GHRMS.MODEL;
using Telerik.Web.UI;

namespace KPIS.GERP.GHRMS.APP.App_UI.UserControls
{
    public partial class PS_AbsenceRules : System.Web.UI.UserControl
    {
        public Main main = new Main();

        private IAbsenceTypeBLL absenceTypeBll = new AbsenceTypeBLL();
        private IEmployeeTypeBLL employeeTypeBll = new EmployeeTypeBLL();
        private IAbsenceRuleBLL ruleBll = new AbsenceRuleBLL();
        private object _dataItem = null;
        public RuleAbsenceService.RuleAbsenceService ruleAbsenceService = new RuleAbsenceService.RuleAbsenceService();

        protected void Page_Load(object sender, EventArgs e)
        { 
            LoadDropdownItem();
                
            if (DataItem != null)
            {                 
                if (!(DataItem is Telerik.Web.UI.GridInsertionObject))
                {
                    int? ruleAbsenceSeq = DataBinder.Eval(DataItem, "Sequence") as int?;
                    LoadModel(ruleAbsenceSeq);

                }
                else
                { 
                    UpdateUi();
                }
                btnUpdate.Visible = !(DataItem is Telerik.Web.UI.GridInsertionObject);
                btnAddnew.Visible = (DataItem is Telerik.Web.UI.GridInsertionObject);
            } 
        }

        public object DataItem
        {
            get
            {
                return this._dataItem;
            }
            set
            {
                this._dataItem = value;
            }
        }

        protected void btnAddnew_Click(object sender, EventArgs e)
        {
            ruleAbsenceService.Insert(Model, new SsMng().EmpSeqI, true);
        }
         
        protected void btnUpdate_Click(object sender, EventArgs e)
        { 
            ruleAbsenceService.Update(Model, new SsMng().EmpSeqI, true);
        }

        protected void btnCancel_Click(object sender, EventArgs e)
        {
            //
        }
        
        /*
        private IAbsenceTypeBLL absenceTypeBll = new AbsenceTypeBLL();
        private IEmployeeTypeBLL employeeTypeBll = new EmployeeTypeBLL();
        private IAbsenceRuleBLL ruleBll = new AbsenceRuleBLL();
        private object _dataItem = null;

        protected void Page_Load(object sender, EventArgs e)
        {
            if (DataItem != null)
            {                
                cbEmployeeType.ListEmployeeTypeComboBox();
                cbAbsenceType.ListAbsenceTypeComboBox();

                if (!(DataItem is Telerik.Web.UI.GridInsertionObject))
                {
                    lblSeq.Text = DataBinder.Eval(DataItem, "Sequence").ToString();
                    var empTypeFromDb = Convert.ToString(DataBinder.Eval(DataItem, "EmployeeType.Sequence"));
                    cmbEmployeeType.SelectedValue = empTypeFromDb;
                    cmbAbsenceType.SelectedValue = Convert.ToString(DataBinder.Eval(DataItem, "AbsenceType.Sequence"));
                    txtQuotaDay.Text = DataBinder.Eval(DataItem, "QuotaDay").ToString();
                    txtQuotaSalary.Text = DataBinder.Eval(DataItem, "QuotaDaySalary").ToString();
                    txtQuotaHalfSalary.Text = DataBinder.Eval(DataItem, "QuotaDayHalfSalary").ToString();
                    txtQuotaCount.Text = DataBinder.Eval(DataItem, "QuotaCount").ToString();
                    txtQuotaDayPerCount.Text = DataBinder.Eval(DataItem, "DayPerCount").ToString();
                    txtRemarks.Text = DataBinder.Eval(DataItem, "Remarks").ToString();
                    incl_nonworkingday.SelectedValue = Convert.ToBoolean(DataBinder.Eval(DataItem, "IncludeNonWorkingDay")) ? "1" : "0";
                    var useSendBeforeType = DataBinder.Eval(DataItem, "UseSendBefore") as AbsenceRuleInfo.UseSendBeforeEnum? ?? AbsenceRuleInfo.UseSendBeforeEnum.NotUse;
                    radCmbSendBeforeType.SelectedValue = useSendBeforeType == AbsenceRuleInfo.UseSendBeforeEnum.NotUse ? "0" :
                        useSendBeforeType == AbsenceRuleInfo.UseSendBeforeEnum.UseSendBefore ? "1" :
                        "-1";
                    radNumTxtSendBefore.Value = Math.Abs(new Main().ConvertNullDouble(DataBinder.Eval(DataItem, "SendBefore")) ?? 0);
                    ltrAbsenceRuleSeq.Text = Convert.ToString(DataBinder.Eval(DataItem, "Sequence"));
                }
                else
                {
                    //SelectedEmployeeType = (string) Session["AbsenceRuleEmployeeType"];
                }
                btnUpdate.Visible = !(DataItem is Telerik.Web.UI.GridInsertionObject);
                btnAddnew.Visible = (DataItem is Telerik.Web.UI.GridInsertionObject);
            }
        }

        public object DataItem
        {
            get
            {
                return this._dataItem;
            }
            set
            {
                this._dataItem = value;
            }
        }

        protected void btnAddnew_Click(object sender, EventArgs e)
        {
            ruleBll.Insert(cmbEmployeeType.SelectedValue
                    , cmbAbsenceType.SelectedValue
                    , decimal.Parse(string.IsNullOrEmpty(txtQuotaDay.Text) ? "0" : txtQuotaDay.Text)
                    , decimal.Parse(string.IsNullOrEmpty(txtQuotaSalary.Text) ? "0" : txtQuotaSalary.Text)
                    , decimal.Parse(string.IsNullOrEmpty(txtQuotaHalfSalary.Text) ? "0" : txtQuotaHalfSalary.Text)
                    , decimal.Parse(string.IsNullOrEmpty(txtQuotaCount.Text) ? "0" : txtQuotaCount.Text)
                    , decimal.Parse(string.IsNullOrEmpty(txtQuotaDayPerCount.Text) ? "0" : txtQuotaDayPerCount.Text)
                    , txtRemarks.Text
                    , 1
                    , incl_nonworkingday.SelectedValue == "1"
                    , GetUseSendBeforeType()
                    , Convert.ToDecimal(radNumTxtSendBefore.Value ?? 0));
        }

        private AbsenceRuleInfo.UseSendBeforeEnum GetUseSendBeforeType()
        {
            switch (radCmbSendBeforeType.SelectedValue)
            {
                case "0":
                    return AbsenceRuleInfo.UseSendBeforeEnum.NotUse;
                case "-1":
                    return AbsenceRuleInfo.UseSendBeforeEnum.UseSendAfter;
                default:
                    return AbsenceRuleInfo.UseSendBeforeEnum.UseSendBefore;
                    
            }
        }

        protected void btnUpdate_Click(object sender, EventArgs e)
        {
            ruleBll.Update(Int32.Parse(lblSeq.Text)
                    , cmbEmployeeType.SelectedValue
                    , cmbAbsenceType.SelectedValue
                    , decimal.Parse(string.IsNullOrEmpty(txtQuotaDay.Text) ? "0" : txtQuotaDay.Text)
                    , decimal.Parse(string.IsNullOrEmpty(txtQuotaSalary.Text) ? "0" : txtQuotaSalary.Text)
                    , decimal.Parse(string.IsNullOrEmpty(txtQuotaHalfSalary.Text) ? "0" : txtQuotaHalfSalary.Text)
                    , decimal.Parse(string.IsNullOrEmpty(txtQuotaCount.Text) ? "0" : txtQuotaCount.Text)
                    , decimal.Parse(string.IsNullOrEmpty(txtQuotaDayPerCount.Text) ? "0" : txtQuotaDayPerCount.Text)
                    , txtRemarks.Text
                    , 1
                    , incl_nonworkingday.SelectedValue == "1"
                    , GetUseSendBeforeType()
                    , Convert.ToDecimal(radNumTxtSendBefore.Value ?? 0));
        }

        protected void btnCancel_Click(object sender, EventArgs e)
        {

        }*/
        public RuleAbsence Model
        {
            get
            {
                var model = new RuleAbsence();

                model.RuleAbsenceId = main.ConvertDefaultInt(lblSeq.Text);

                // Section 1
                model.AbsenceTypeId = main.ConvertDefaultInt(cmbAbsenceType.SelectedValue);
                model.EmpTypeId = main.ConvertDefaultInt(cmbEmployeeType.SelectedValue);

                // Section 2
                model.IncludeNwd = incl_nonworkingday.SelectedValue == "1";
                model.DayLimit = cmbQuotaDayConfig.SelectedValue == "LimitTo" && txtQuotaDay.Value.HasValue ? main.ConvertNullDecimal(txtQuotaDay.Value.Value) : null;
                model.DayCarryType = (DayCarryType)Enum.Parse(typeof(DayCarryType), cmbCarryQuotaConfig.SelectedValue);
                model.DayCarryLimit = main.ConvertNullDecimal(txtCarryQuota.Value);
                model.TimeLimit = cmbQuotaCountConfig.SelectedValue == "LimitTo" && txtQuotaCount.Value.HasValue ? main.ConvertNullDecimal(txtQuotaCount.Value) : null;
                model.DayPerTimeLimit = cmbQuotaDayPerSingleTimeConfig.SelectedValue == "LimitTo" && txtQuotaDayPerSingleTime.Value.HasValue ? main.ConvertNullDecimal(txtQuotaDayPerSingleTime.Value) : null;
                switch (cmbSendBeforeType.SelectedValue)
                {
                    case "0": // ไม่ใช้เงื่อนไขล่วงหน้า 
                        model.SendBefore = null;
                        break;
                    case "1": // ต้องล่วงหน้าอย่างน้อย 
                        model.SendBefore = Convert.ToInt32(Math.Abs(txtSendBefore.Value ?? 0));
                        break;
                    case "-1": // สามารถย้อนหลังได้แต่ไม่ให้เกิน
                        model.SendBefore = -Convert.ToInt32(Math.Abs(txtSendBefore.Value ?? 0));
                        break;
                    default:
                        break;
                }

                // Section 3
                model.DayLimitFullSalary = cmbQuotaSalaryConfig.SelectedValue == "LimitTo" && txtQuotaSalary.Value.HasValue ? main.ConvertNullDecimal(txtQuotaSalary.Value) : null;
                model.DayLimitHalfSalary = cmbQuotaHalfSalary.SelectedValue == "LimitTo" && txtQuotaHalfSalary.Value.HasValue ? main.ConvertNullDecimal(txtQuotaHalfSalary.Value) : null;
                model.GenderSeq = main.ConvertNullInt(rblGenderSeq.SelectedValue);
                model.Remarks = txtRemarks.Text;

                // Section 4
                model.RecordStatus = lblRecordStatus.Text;
                model.CreatedBy = main.ConvertNullInt(lblCreatedBy.Text);
                model.CreatedWhen = main.ConvertNullDateTime(lblCreatedWhen.Text);
                model.UpdatedBy = main.ConvertNullInt(lblUpdatedBy.Text);
                model.UpdatedWhen = main.ConvertNullDateTime(lblUpdatedWhen.Text);
                //model.EmpType = ruleAbsenceService.MasEmployeeTypes.FirstOrDefault(o=>o.EmpTypeId == model.EmpTypeId);
                //model.AbsenceType = db.PsAbsenceTypes.FirstOrDefault(o=>o.AbsenceTypeId == model.AbsenceTypeId);

                foreach (PropertyInfo property in model.GetType().GetProperties().Where(o => !o.Name.EndsWith("Specified")))
                {
                    string prop = String.Format("{0}Specified", property.Name);
                    PropertyInfo target = model.GetType().GetProperty(prop);
                    if (target != null)
                    {
                        PropertyInfo src = model.GetType().GetProperty(property.Name);
                        bool currentValue = (bool)target.GetValue(model, null);
                        bool hasValue = (src.GetValue(model, null) == null ? false : true);
                        if (currentValue != hasValue)
                            target.SetValue(model, hasValue, null);
                    }
                }


                return model;
            }

            set
            {
                var model = value;

                lblSeq.Text = model.RuleAbsenceId != 0 ? "" + model.RuleAbsenceId : null;

                // Section 1
                if (model.AbsenceTypeId != 0)
                {
                    if (cmbAbsenceType.Items.All(o => o.Value != "" + model.AbsenceTypeId))
                    {
                        throw new NullReferenceException();
                    }
                    cmbAbsenceType.SelectedValue = "" + model.AbsenceTypeId;
                }
                else
                {
                    cmbAbsenceType.SelectedIndex = -1;
                }
                if (model.EmpTypeId != 0)
                {
                    if (cmbEmployeeType.Items.All(o => o.Value != "" + model.EmpTypeId))
                    {
                        throw new NullReferenceException();
                    }
                    cmbEmployeeType.SelectedValue = "" + model.EmpTypeId;
                }
                else
                {
                    cmbEmployeeType.SelectedIndex = -1;
                }

                // Section 2
                incl_nonworkingday.SelectedValue = model.IncludeNwd ? "1" : "0";
                if (model.DayLimit == null)
                {
                    if (cmbQuotaDayConfig.Items.All(o => o.Value != "NotLimit"))
                    {
                        throw new NullReferenceException();
                    }
                    cmbQuotaDayConfig.SelectedValue = "NotLimit";
                    txtQuotaDay.Value = null;
                }
                else
                {
                    if (cmbQuotaDayConfig.Items.All(o => o.Value != "LimitTo"))
                    {
                        throw new NullReferenceException();
                    }
                    cmbQuotaDayConfig.SelectedValue = "LimitTo";
                    txtQuotaDay.Value = main.ConvertNullDouble(model.DayLimit);
                }

                if (cmbCarryQuotaConfig.Items.All(o => o.Value != Convert.ToString((int)model.DayCarryType)))
                {
                    throw new NullReferenceException();
                }
                cmbCarryQuotaConfig.SelectedValue = Convert.ToString((int)model.DayCarryType);
                if (model.DayCarryType == DayCarryType.NoCarry)
                {
                    txtCarryQuota.Value = null;
                }
                else
                {
                    txtCarryQuota.Value = main.ConvertNullDouble(model.DayCarryLimit);
                }

                if (model.TimeLimit == null)
                {
                    if (cmbQuotaCountConfig.Items.All(o => o.Value != "NotLimit"))
                    {
                        throw new NullReferenceException();
                    }
                    cmbQuotaCountConfig.SelectedValue = "NotLimit";
                    txtQuotaCount.Value = null;
                }
                else
                {
                    if (cmbQuotaCountConfig.Items.All(o => o.Value != "LimitTo"))
                    {
                        throw new NullReferenceException();
                    }
                    cmbQuotaCountConfig.SelectedValue = "LimitTo";
                    txtQuotaCount.Value = main.ConvertNullDouble(model.TimeLimit);
                }

                if (model.DayPerTimeLimit == null)
                {
                    if (cmbQuotaDayPerSingleTimeConfig.Items.All(o => o.Value != "NotLimit"))
                    {
                        throw new NullReferenceException();
                    }
                    cmbQuotaDayPerSingleTimeConfig.SelectedValue = "NotLimit";
                    txtQuotaDayPerSingleTime.Value = null;
                }
                else
                {
                    if (cmbQuotaDayPerSingleTimeConfig.Items.All(o => o.Value != "LimitTo"))
                    {
                        throw new NullReferenceException();
                    }
                    cmbQuotaDayPerSingleTimeConfig.SelectedValue = "LimitTo";
                    txtQuotaDayPerSingleTime.Value = main.ConvertNullDouble(model.DayPerTimeLimit);
                }

                if (model.SendBefore == null)
                {
                    if (cmbSendBeforeType.Items.All(o => o.Value != "0"))
                    {
                        throw new NullReferenceException();
                    }
                    cmbSendBeforeType.SelectedValue = "0";
                    txtSendBefore.Value = null;
                }
                else if (model.SendBefore > 0)
                {
                    if (cmbSendBeforeType.Items.All(o => o.Value != "1"))
                    {
                        throw new NullReferenceException();
                    }
                    cmbSendBeforeType.SelectedValue = "1";
                    txtSendBefore.Value = Math.Abs(model.SendBefore ?? 0);
                }
                else if (model.SendBefore < 0)
                {
                    if (cmbSendBeforeType.Items.All(o => o.Value != "-1"))
                    {
                        throw new NullReferenceException();
                    }
                    cmbSendBeforeType.SelectedValue = "-1";
                    txtSendBefore.Value = Math.Abs(model.SendBefore ?? 0);
                }

                // Section 3 
                if (model.DayLimitFullSalary == null)
                {
                    if (cmbQuotaSalaryConfig.Items.All(o => o.Value != "NotLimit"))
                    {
                        throw new NullReferenceException();
                    }
                    cmbQuotaSalaryConfig.SelectedValue = "NotLimit";
                    txtQuotaSalary.Value = null;
                }
                else
                {
                    if (cmbQuotaSalaryConfig.Items.All(o => o.Value != "LimitTo"))
                    {
                        throw new NullReferenceException();
                    }
                    cmbQuotaSalaryConfig.SelectedValue = "LimitTo";
                    txtQuotaSalary.Value = main.ConvertNullDouble(model.DayLimitFullSalary);
                }
                if (model.DayLimitHalfSalary == null)
                {
                    if (cmbQuotaHalfSalary.Items.All(o => o.Value != "NotLimit"))
                    {
                        throw new NullReferenceException();
                    }
                    cmbQuotaHalfSalary.SelectedValue = "NotLimit";
                    txtQuotaHalfSalary.Value = null;
                }
                else
                {
                    if (cmbQuotaHalfSalary.Items.All(o => o.Value != "LimitTo"))
                    {
                        throw new NullReferenceException();
                    }
                    cmbQuotaHalfSalary.SelectedValue = "LimitTo";
                    txtQuotaHalfSalary.Value = main.ConvertNullDouble(model.DayLimitHalfSalary);
                }
                rblGenderSeq.SelectedValue = "" + model.GenderSeq;
                txtRemarks.Text = model.Remarks;

                // Section 4
                lblRecordStatus.Text = model.RecordStatus;
                lblCreatedBy.Text = Convert.ToString(model.CreatedBy);
                lblCreatedWhen.Text = Convert.ToString(model.CreatedWhen);
                lblUpdatedBy.Text = Convert.ToString(model.UpdatedBy);
                lblUpdatedWhen.Text = Convert.ToString(model.UpdatedWhen);

                UpdateUi();
            }
        }

        private void UpdateUi()
        {
            var b1 = txtQuotaDay.Enabled = cmbQuotaDayConfig.SelectedValue == "LimitTo";
            if (b1 && !txtQuotaDay.Value.HasValue)
            {
                txtQuotaDay.Value = txtQuotaDay.MinValue;
            }
            var b2 = txtCarryQuota.Enabled = cmbCarryQuotaConfig.SelectedValue == "2";
            if (b2 && !txtCarryQuota.Value.HasValue)
            {
                txtCarryQuota.Value = txtCarryQuota.MinValue;
            }
            var b3 = txtQuotaCount.Enabled = cmbQuotaCountConfig.SelectedValue == "LimitTo";
            if (b3 && !txtQuotaCount.Value.HasValue)
            {
                txtQuotaCount.Value = txtQuotaCount.MinValue;
            }
            var b4 = txtQuotaDayPerSingleTime.Enabled = cmbQuotaDayPerSingleTimeConfig.SelectedValue == "LimitTo";
            if (b4 && !txtQuotaDayPerSingleTime.Value.HasValue)
            {
                txtQuotaDayPerSingleTime.Value = txtQuotaDayPerSingleTime.MinValue;
            }

            var b5 = txtSendBefore.Enabled = cmbSendBeforeType.SelectedValue != "0";
            if (b5 && !txtSendBefore.Value.HasValue)
            {
                txtSendBefore.Value = txtSendBefore.MinValue;
            }
            var b6 = txtQuotaSalary.Enabled = cmbQuotaSalaryConfig.SelectedValue == "LimitTo";
            if (b6 && !txtQuotaSalary.Value.HasValue)
            {
                txtQuotaSalary.Value = txtQuotaSalary.MinValue;
            }
            var b7 = txtQuotaHalfSalary.Enabled = cmbQuotaHalfSalary.SelectedValue == "LimitTo";
            if (b7 && !txtQuotaHalfSalary.Value.HasValue)
            {
                txtQuotaHalfSalary.Value = txtQuotaHalfSalary.MinValue;
            }
        }

        public void LoadDropdownItem()
        {
            foreach (var data in absenceTypeBll.ListAbsenceTypes())
            {
                cmbAbsenceType.Items.Add(new RadComboBoxItem(data.Name, "" + data.Sequence));
            }
            foreach (var data in employeeTypeBll.ListEmployeeTypes())
            {
                cmbEmployeeType.Items.Add(new RadComboBoxItem(data.Name, "" + data.Sequence));
            }
        }

        public void LoadModel(int? ruleAbsenceId = null)
        {
            var model = ruleAbsenceService.SelectOne(ruleAbsenceId.Value, true);
            Model = model;
        }

        protected void changeConfigType(object sender, RadComboBoxSelectedIndexChangedEventArgs e)
        {
            UpdateUi();
        }
    }
}